package com.devenv.controller;

import com.devenv.dto.*;
import com.devenv.entity.SystemConfig;
import com.devenv.service.SystemConfigService;
import com.devenv.common.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Max;

import java.util.List;
import java.util.Map;

/**
 * 系统配置控制器
 * <p>
 * 提供系统配置相关的REST API接口，包括配置管理、公开配置查询等功能
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/config")
@RequiredArgsConstructor
@Validated
public class SystemConfigController {

    private final SystemConfigService systemConfigService;

    /**
     * 获取所有公开配置
     */
    @GetMapping("/public")
    public ResponseEntity<Result<Map<String, String>>> getPublicConfigs() {
        log.debug("获取所有公开配置");
        try {
            Map<String, String> configs = systemConfigService.getPublicConfigMap();
            return ResponseEntity.ok(Result.success(configs));
        } catch (Exception e) {
            log.error("获取公开配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 根据配置键获取配置值
     */
    @GetMapping("/value/{configKey}")
    public ResponseEntity<Result<String>> getConfigValue(@PathVariable String configKey) {
        log.debug("根据配置键获取配置值: {}", configKey);
        try {
            String value = systemConfigService.getConfigValue(configKey);
            if (value != null) {
                return ResponseEntity.ok(Result.success(value));
            } else {
                return ResponseEntity.badRequest().body(Result.error("配置不存在"));
            }
        } catch (Exception e) {
            log.error("获取配置值失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 根据ID获取系统配置
     */
    @GetMapping("/{id}")
    public ResponseEntity<Result<SystemConfigDTO>> getSystemConfigById(@PathVariable Long id) {
        log.debug("根据ID获取系统配置，ID: {}", id);
        try {
            SystemConfig config = systemConfigService.findById(id)
                    .orElseThrow(() -> new IllegalArgumentException("系统配置不存在"));
            SystemConfigDTO dto = convertToDTO(config);
            return ResponseEntity.ok(Result.success(dto));
        } catch (Exception e) {
            log.error("获取系统配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 分页查询系统配置
     */
    @GetMapping
    public ResponseEntity<Result<Page<SystemConfigDTO>>> getSystemConfigs(
            @RequestParam(defaultValue = "0") @Min(0) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size,
            @RequestParam(defaultValue = "createdAt") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {
        log.debug("分页查询系统配置，页码: {}, 大小: {}", page, size);
        try {
            Sort.Direction direction = "desc".equalsIgnoreCase(sortDir) 
                ? Sort.Direction.DESC : Sort.Direction.ASC;
            Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sortBy));
            
            Page<SystemConfig> configPage = systemConfigService.findAll(pageable);
            Page<SystemConfigDTO> dtoPage = configPage.map(this::convertToDTO);
            
            return ResponseEntity.ok(Result.success(dtoPage));
        } catch (Exception e) {
            log.error("查询系统配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 搜索系统配置
     */
    @GetMapping("/search")
    public ResponseEntity<Result<Page<SystemConfigDTO>>> searchConfigs(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") @Min(0) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size) {
        log.debug("搜索系统配置，关键字: {}", keyword);
        try {
            Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
            Page<SystemConfig> configPage = systemConfigService.searchConfigs(keyword, pageable);
            Page<SystemConfigDTO> dtoPage = configPage.map(this::convertToDTO);
            
            return ResponseEntity.ok(Result.success(dtoPage));
        } catch (Exception e) {
            log.error("搜索系统配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 创建系统配置
     */
    @PostMapping
    public ResponseEntity<Result<SystemConfigDTO>> createConfig(@Valid @RequestBody SystemConfigDTO dto) {
        log.info("创建系统配置，配置键: {}", dto.getConfigKey());
        try {
            SystemConfig config = systemConfigService.createConfig(dto);
            SystemConfigDTO responseDTO = convertToDTO(config);
            return ResponseEntity.ok(Result.success(responseDTO, "配置创建成功"));
        } catch (Exception e) {
            log.error("创建系统配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 更新系统配置
     */
    @PutMapping("/{id}")
    public ResponseEntity<Result<SystemConfigDTO>> updateConfig(
            @PathVariable Long id,
            @Valid @RequestBody SystemConfigDTO dto) {
        log.info("更新系统配置，ID: {}", id);
        try {
            SystemConfig config = systemConfigService.updateConfig(id, dto);
            SystemConfigDTO responseDTO = convertToDTO(config);
            return ResponseEntity.ok(Result.success(responseDTO, "配置更新成功"));
        } catch (Exception e) {
            log.error("更新系统配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 更新配置值
     */
    @PutMapping("/value/{configKey}")
    public ResponseEntity<Result<String>> updateConfigValue(
            @PathVariable String configKey,
            @RequestBody UpdateConfigValueRequest request) {
        log.info("更新配置值，配置键: {}", configKey);
        try {
            boolean updated = systemConfigService.updateConfigValue(configKey, request.getConfigValue());
            if (updated) {
                return ResponseEntity.ok(Result.success(null, "配置值更新成功"));
            } else {
                return ResponseEntity.badRequest().body(Result.error("配置不存在"));
            }
        } catch (Exception e) {
            log.error("更新配置值失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 删除系统配置
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Result<String>> deleteConfig(@PathVariable Long id) {
        log.info("删除系统配置，ID: {}", id);
        try {
            boolean deleted = systemConfigService.deleteConfig(id);
            if (deleted) {
                return ResponseEntity.ok(Result.success(null, "配置删除成功"));
            } else {
                return ResponseEntity.badRequest().body(Result.error("配置不存在"));
            }
        } catch (Exception e) {
            log.error("删除系统配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 初始化默认配置
     */
    @PostMapping("/init")
    public ResponseEntity<Result<String>> initializeDefaultConfigs() {
        log.info("初始化默认系统配置");
        try {
            systemConfigService.initializeDefaultConfigs();
            return ResponseEntity.ok(Result.success(null, "默认配置初始化成功"));
        } catch (Exception e) {
            log.error("初始化默认配置失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 清除配置缓存
     */
    @PostMapping("/cache/clear")
    public ResponseEntity<Result<String>> clearConfigCache(@RequestParam(required = false) String configKey) {
        log.info("清除配置缓存，配置键: {}", configKey);
        try {
            if (configKey != null) {
                systemConfigService.evictConfigCache(configKey);
            } else {
                systemConfigService.evictAllConfigCache();
            }
            return ResponseEntity.ok(Result.success(null, "缓存清除成功"));
        } catch (Exception e) {
            log.error("清除配置缓存失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 获取系统状态信息
     */
    @GetMapping("/system/status")
    public ResponseEntity<Result<SystemStatus>> getSystemStatus() {
        log.debug("获取系统状态信息");
        try {
            SystemStatus status = new SystemStatus();
            status.setMaintenanceMode(systemConfigService.isMaintenanceMode());
            status.setRegistrationEnabled(systemConfigService.isRegistrationEnabled());
            status.setSystemName(systemConfigService.getConfigValue("system.name", "DevEnv开源版"));
            status.setSystemVersion(systemConfigService.getConfigValue("system.version", "1.0.0"));
            status.setSystemDescription(systemConfigService.getConfigValue("system.description", "DevEnv开源软件管理平台"));
            
            return ResponseEntity.ok(Result.success(status));
        } catch (Exception e) {
            log.error("获取系统状态信息失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 转换SystemConfig实体为SystemConfigDTO
     */
    private SystemConfigDTO convertToDTO(SystemConfig config) {
        SystemConfigDTO dto = new SystemConfigDTO();
        dto.setId(config.getId());
        dto.setConfigKey(config.getConfigKey());
        dto.setConfigValue(config.getConfigValue());
        dto.setDescription(config.getDescription());
        dto.setIsSystem(config.getIsSystem());
        dto.setIsPublic(config.getIsPublic());
        dto.setCreatedAt(config.getCreatedAt());
        dto.setUpdatedAt(config.getUpdatedAt());
        return dto;
    }

    /**
     * 更新配置值请求DTO
     */
    public static class UpdateConfigValueRequest {
        @jakarta.validation.constraints.NotBlank(message = "配置值不能为空")
        private String configValue;

        public String getConfigValue() { return configValue; }
        public void setConfigValue(String configValue) { this.configValue = configValue; }
    }

    /**
     * 系统状态信息
     */
    public static class SystemStatus {
        private boolean maintenanceMode;
        private boolean registrationEnabled;
        private String systemName;
        private String systemVersion;
        private String systemDescription;

        public boolean isMaintenanceMode() { return maintenanceMode; }
        public void setMaintenanceMode(boolean maintenanceMode) { this.maintenanceMode = maintenanceMode; }
        public boolean isRegistrationEnabled() { return registrationEnabled; }
        public void setRegistrationEnabled(boolean registrationEnabled) { this.registrationEnabled = registrationEnabled; }
        public String getSystemName() { return systemName; }
        public void setSystemName(String systemName) { this.systemName = systemName; }
        public String getSystemVersion() { return systemVersion; }
        public void setSystemVersion(String systemVersion) { this.systemVersion = systemVersion; }
        public String getSystemDescription() { return systemDescription; }
        public void setSystemDescription(String systemDescription) { this.systemDescription = systemDescription; }
    }
}
